package com.sayice.icemusic.util.encrypt;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * RSA 加密工具类
 *
 * @author shubing
 */
public class RSAUtils {
    /**
     * 加密
     */
    public static String encrypt(String data, String pubKey, String modulus) {
        List<String> chars = Arrays.asList(data.split(""));
        Collections.reverse(chars);
        StringBuilder strBuilder = new StringBuilder();
        for (String s : chars) {
            strBuilder.append(s);
        }
        String reversedData = strBuilder.toString();
        BigInteger biText = new BigInteger(1, reversedData.getBytes());
        BigInteger biEx = new BigInteger(1, hexToBytes(pubKey));
        BigInteger biMod = new BigInteger(1, hexToBytes(modulus));
        String biRet = biText.modPow(biEx, biMod).toString(16);
        return zerofill(biRet, 256);
    }
    
    /**
     * 16进制字符串转字节数组
     *
     * @param str 字符串
     * @return str对应的字节数组
     */
    private static byte[] hexToBytes(String str) {
        if (str == null || "".equals(str)) {
            return null;
        }
        int length = str.length() / 2;
        char[] hexChars = str.toCharArray();
        byte[] bytes = new byte[length];
        final String hexDigits = "0123456789abcdef";
        for (int i = 0; i < length; i++) {
            // 两个字符对应一个byte
            int pos = i * 2;
            int h = hexDigits.indexOf(hexChars[pos]) << 4;
            int l = hexDigits.indexOf(hexChars[pos + 1]);
            // 非 16 进制字符
            if (h == -1 || l == -1) {
                return null;
            }
            bytes[i] = (byte) (h | l);
        }
        return bytes;
    }
    
    /**
     * 用 “0” 填充字符串至某长度
     *
     * @param str  待填充字符串
     * @param size 总长度
     * @return 返回填充后的字符串
     */
    private static String zerofill(String str, int size) {
        StringBuilder strBuilder = new StringBuilder(str);
        while (strBuilder.length() < size) {
            strBuilder.insert(0, "0");
        }
        return strBuilder.toString();
    }
}
